package com.mazaiting.auth.utils;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mazaiting.auth.constant.SecurityConst;
import com.mazaiting.auth.domain.ClientInfo;
import com.mazaiting.auth.enums.AuthenticationIdentityEnum;
import com.mazaiting.auth.enums.RefreshTypeEnum;
import com.mazaiting.common.core.domain.result.ResultCode;
import com.mazaiting.common.core.ex.exceptions.EmptyObjectException;
import com.mazaiting.web.utils.HttpUtil;
import com.mazaiting.web.utils.JwtUtil;
import com.nimbusds.jose.JWSObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.util.Base64;

/**
 * 请求工具类
 */
@Slf4j
public class RequestUtil {


    /**
     * 获取登录认证的客户端ID
     * 1. 先从请求头中取 clientId:clientSecret
     * 2. 再从请求参数中取 clientId 再取 client_id
     *
     * @return 客户端 ID
     */
    public static ClientInfo getOAuth2ClientId() throws EmptyObjectException {
        // 获取授权信息
        String basic = JwtUtil.getOauthClient();
        String basicPlainText = new String(Base64.getDecoder().decode(basic.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8);
        //client:secret
        String[] info = basicPlainText.split(":");
        if (info.length > 1) {
            ClientInfo clientInfo = new ClientInfo();
            clientInfo.setClientId(info[0]);
            clientInfo.setClientSecret(info[1]);
            return clientInfo;
        }
        throw new EmptyObjectException(ResultCode.PARAM_TYPE_ERROR);
    }


    /**
     * 解析JWT获取认证身份标识
     * 1. 先从请求体中读取
     * 2. 再从请求参数中读取
     *
     * @return 客户端标识
     */
    public static String getAuthenticationIdentity() throws EmptyObjectException, ParseException {
        String refreshToken = getRefreshToken();

        // 解析认证信息
        String payload = StrUtil.toString(JWSObject.parse(refreshToken).getPayload());
        JSONObject jsonObject = JSON.parseObject(payload);

        String authenticationIdentity = jsonObject.getString(SecurityConst.KEY_AUTHENTICATION_IDENTITY);
        if (StrUtil.isBlank(authenticationIdentity)) {
            authenticationIdentity = AuthenticationIdentityEnum.USERNAME.getValue();
        }
        return authenticationIdentity;
    }

    /**
     * 解析JWT获取刷新类型
     * 1. 先从请求体中读取
     * 2. 再从请求参数中读取
     *
     * @return 客户端标识
     */
    public static String getRefreshType() throws EmptyObjectException, ParseException {
        String refreshToken = getRefreshToken();

        // 解析认证信息
        String payload = StrUtil.toString(JWSObject.parse(refreshToken).getPayload());
        JSONObject jsonObject = JSON.parseObject(payload);

        String refreshType = jsonObject.getString(SecurityConst.KEY_REFRESH_TYPE);
        if (StringUtils.hasLength(refreshType)) {
            refreshType = RefreshTypeEnum.CLIENT_MANAGER.name();
        }
        return refreshType;
    }

    /**
     * 获取刷新令牌
     *
     * @return 刷新令牌
     */
    public static String getRefreshToken() throws EmptyObjectException {
        HttpServletRequest request = HttpUtil.getHttpServletRequest();
        // 请求头中读取 refresh_token
        String refreshToken = request.getHeader(SecurityConst.KEY_REFRESH_TOKEN);
        if (!StringUtils.hasLength(refreshToken)) {
            // 读取 refreshToken
            refreshToken = request.getParameter(SecurityConst.KEY_REFRESH_TOKEN_NEW);
        }
        if (!StringUtils.hasLength(refreshToken)) {
            // 读取 refresh_token
            refreshToken = request.getParameter(SecurityConst.KEY_REFRESH_TOKEN);
        }
        if (!StringUtils.hasLength(refreshToken)) {
            throw new EmptyObjectException(ResultCode.PARAM_TYPE_ERROR);
        }
        return refreshToken;
    }

    /**
     * 获取授权类型
     *
     * @return 授权类型
     */
    public static String getGrantType() throws EmptyObjectException {
        return HttpUtil.getHeader(SecurityConst.KEY_GRANT_TYPE);
    }

}
